package pl.wroc.pwr.mss.server.util;

import java.awt.Component;

import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

/**
 * Klasa uzytkowa wspierajaca operowanie na tablicach swingowych.
 * 
 * @author mjagus
 */
public class JTableUtils
{
    /**
     * Zmienia szerokosci kolumn w swingowej tabeli tak, aby dopasowaly sie one
     * do elementow znajdujacych sie w wierszach tej tabeli.
     * 
     * @param table Tabela ktorej kolumny beda modyfikowane
     */
    public static void adjustColumns(JTable table)
    {
        int columns = table.getColumnCount();

        for(int column = 0; column < columns; column++)
        {
            TableColumn tableColumn = table.getColumnModel().getColumn(column);

            if(tableColumn.getResizable())
            {
                int columnHeaderWidth = getColumnHeaderWidth(table, column);
                int columnDataWidth   = getColumnDataWidth(table, column);
                int preferredWidth    = Math.max(columnHeaderWidth, columnDataWidth);

                updateTableColumn(table, column, preferredWidth);
            }
        }
    }

    /**
     * Zwraca pozadana szerokosc (w pikselach) wybranego naglowka tabeli.
     * Pozadana szerokosc informuje, jaka powinna byc szerokosc kolumny, aby
     * calkowicie zmiescil sie w niej wyswietlany komponent graficzny.
     * 
     * @param table Tabela ktora sprawdzamy
     * @param column Numer kolumny w ktorej znajduje sie naglowek
     * @return Pozadana szerokosc naglowka tabeli w danej kolumnie
     */
    public static int getColumnHeaderWidth(JTable table, int column)
    {
        TableColumn tableColumn = table.getColumnModel().getColumn(column);
        Object value = tableColumn.getHeaderValue();
        TableCellRenderer renderer = tableColumn.getHeaderRenderer();

        if(renderer == null)
            renderer = table.getTableHeader().getDefaultRenderer();

        Component c = renderer.getTableCellRendererComponent(table, value, false, false, -1, column);
        return c.getPreferredSize().width;
    }

    /**
     * Zwraca pozadana szerokosc (w pikselach) wybranej kolumny tabeli.
     * Pozadana szerokosc informuje, jaka powinna byc szerokosc kolumny, aby
     * calkowicie zmiescil sie w niej najwiekszy, wyswietlany komponent
     * graficzny.
     * 
     * @param table Tabela ktora sprawdzamy
     * @param column Numer kolumny dla ktorej chcemy uzyskac pozadna szerokosc
     * @return Pozadana szerokosc kolumny
     */
    public static int getColumnDataWidth(JTable table, int column)
    {
        int preferredWidth = 0;
        int maxWidth = table.getColumnModel().getColumn(column).getMaxWidth();

        for(int row = 0; row < table.getRowCount() && preferredWidth < maxWidth; row++)
        {
            TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
            Component c = table.prepareRenderer(cellRenderer, row, column);
            int cellWidth = c.getPreferredSize().width + table.getIntercellSpacing().width;
            preferredWidth = Math.max(preferredWidth, cellWidth);
        }

        return preferredWidth;
    }

    /**
     * Zmienia szerokosc wybranej kolumny tabeli na zadana.
     * 
     * @param table Tabela w ktorej modyfikujemy szerokosc kolumny
     * @param column Numer kolumny w tabeli
     * @param width Szerokosc jaka chcemy ustawic dla kolumny
     */
    public static void updateTableColumn(JTable table, int column, int width)
    {
        TableColumn tableColumn = table.getColumnModel().getColumn(column);

        table.getTableHeader().setResizingColumn(tableColumn);
        tableColumn.setWidth(width);
    }
}
